home *** CD-ROM | disk | FTP | other *** search
Text File | 1995-11-08 | 14.8 KB | 514 lines | [TEXT/MPS ] |
- //========================================================================================
- //
- // File: FWMemMgr.cpp
- // Release Version: $ 1.0d11 $
- //
- // Copyright: (c) 1993, 1995 by Apple Computer, Inc., all rights reserved.
- //
- //========================================================================================
-
- #include "FWFound.hpp"
-
- #ifndef FWMEMMGR_H
- #include "FWMemMgr.h"
- #endif
-
- #ifndef FWEXCDEF_H
- #include "FWExcDef.h"
- #endif
-
- #ifndef FWMEMTAS_H
- #include "FWMemTas.h"
- #endif
-
- #ifndef FWMEMHLP_H
- #include "FWMemHlp.h"
- #endif
-
- #ifndef FWNEW_H
- #include "FWNew.h"
- #endif
-
- #if defined(FW_BUILD_MAC) && !defined(__OSUTILS__)
- #include <OSUtils.h>
- #endif
-
- #if defined(FW_BUILD_MAC) && !defined(__MEMORY__)
- #include <Memory.h>
- #endif
-
- #if defined(FW_BUILD_WIN) && !defined(_INC_WINDOWS)
- #include <Windows.h>
- #endif
-
- #if defined(FW_BUILD_WIN) && !defined(_INC_WINDOWSX)
- #include <WindowsX.h>
- #endif
-
- #if !defined(FW_qUsePlatformAlloc) && !defined(FW_qUseCRuntimeAlloc)
-
- #ifdef FW_BUILD_WIN
- #include <MMStubs.h>
- #endif
-
- #ifdef FW_BUILD_MAC
- #include <MemMgr.h>
- #endif
-
- #endif
-
- #include <string.h>
-
- #if defined(__SC__) && defined(FW_BUILD_WIN)
-
- #if !defined(__LIMITS_H)
- #include <limits.h>
- #endif
-
- #if !defined(__HUGEPTR_H) && defined(FW_BUILD_WIN16)
- #include <hugeptr.h>
- #endif
-
- #endif
-
- #if FW_LIB_EXPORT_PRAGMAS
- #pragma lib_export on
- #endif
-
- #define PRIV_CLEAR_MEM_ON_ALLOC
-
- // It'd be cool to let this be set at program startup using InitializationFile setting
- #ifdef PRIV_CLEAR_MEM_ON_ALLOC
- const unsigned char kKnownRawByte = 0;
- #else
- const unsigned char kKnownRawByte = 0x5A;
- #endif
-
- #ifdef FW_BUILD_MAC
- #pragma segment FWMemory
- #endif
-
- //========================================================================================
- // Global procedures
- //========================================================================================
-
- #ifdef FW_BUILD_MAC
- //----------------------------------------------------------------------------------------
- // SetStackSpace
- //----------------------------------------------------------------------------------------
-
- void SetStackSpace(long numBytes)
- {
- long newLimit;
-
- // Make sure numBytes is even
- if (numBytes % 2) numBytes++;
-
- newLimit = (long)LMGetCurStackBase() - numBytes;
- if ((long)GetApplLimit() > newLimit)
- SetApplLimit((Ptr)newLimit);
- } // SetStackSpace
- #endif
-
-
- #if defined(FW_BUILD_WIN) && defined(FW_qUsePlatformAlloc)
- //----------------------------------------------------------------------------------------
- // GetPointer
- //----------------------------------------------------------------------------------------
-
- static void* GetPointer(HANDLE h)
- {
- return (void*)::GlobalLock(h);
- }
- #endif
-
- #if defined(FW_BUILD_WIN) && defined(FW_qUsePlatformAlloc)
- //----------------------------------------------------------------------------------------
- // GetHandle
- //----------------------------------------------------------------------------------------
-
- static HANDLE GetHandle(void* p)
- {
- return p != NULL ? GlobalPtrHandle(p) : NULL;
- }
- #endif
-
- #ifdef FW_SET_NEW_HANDLER
- //----------------------------------------------------------------------------------------
- // set_new_handler
- //----------------------------------------------------------------------------------------
-
- FW_PFVV set_new_handler(FW_PFVV handler)
- {
- FW_SPrivMemoryGlobals& globals = FW_CMemoryTaskGlobals::GetMemoryGlobals();
- FW_PFVV oldHandler = globals.gNewHandler;
- globals.gNewHandler = handler;
- return oldHandler;
- }
- #endif
-
- //========================================================================================
- // CLASS FW_CMemoryManager
- //========================================================================================
-
- //----------------------------------------------------------------------------------------
- // FW_CMemoryManager::GetMemoryHeap
- //----------------------------------------------------------------------------------------
-
- MemHeap* FW_CMemoryManager::GetMemoryHeap()
- {
- MemHeap* heap = FW_CMemoryTaskGlobals::GetMemoryGlobals().gMemoryHeap;
- FW_ASSERT(heap != NULL);
-
- return heap;
- }
-
- //----------------------------------------------------------------------------------------
- // FW_CMemoryManager::DefaultNewHandler
- //----------------------------------------------------------------------------------------
-
- void FW_CMemoryManager::DefaultNewHandler()
- {
- FW_Failure(FW_xMemoryExhausted);
- }
-
- //----------------------------------------------------------------------------------------
- // FW_CMemoryManager::AddOffsetToPointer
- //----------------------------------------------------------------------------------------
-
- void *FW_CMemoryManager::AddOffsetToPointer(void *pointer, unsigned long Offset)
- {
- #if defined(FW_BUILD_MAC) || defined(FW_BUILD_WIN32)
- return (void *)((char *)pointer + Offset);
- #elif defined(__SC__) && defined(FW_BUILD_WIN16)
- // If 'Offset' is not less than the maximum signed LONG Value, consider it an fError.
- // We could program for these cases, but it is More than likely an fError.
- FW_ASSERT(Offset < (unsigned long)LONG_MAX);
-
- // Symantec C++ note: hugeptr_add(p,o) is a macro that calls the function:
- // hugeptr_add(p, sizeof(*p) * o)
- // Thus, the pointer passed to hugeptr_add() must be 'char *' type.
- char * typedPointer = pointer;
- signed long signedLongOffset = Offset;
-
- // The call to hugeptr_add() is not scoped with '::' because Symantec C++
- // first uses a macro and the macro fails to compile when scoped with '::'.
- return hugeptr_add(typedPointer, signedLongOffset);
- #else
- return (char __huge* pointer) + Offset;
- #endif
- }
-
- //----------------------------------------------------------------------------------------
- // FW_CMemoryManager::CopyMemory -
- //----------------------------------------------------------------------------------------
- void FW_CMemoryManager::CopyMemory(const void* const source,
- void* const destination,
- unsigned long bytesToMove)
- {
- FW_ASSERT(source != 0);
- FW_ASSERT(destination != 0);
-
- #if defined(FW_BUILD_MAC)
- ::BlockMoveData(source, destination, bytesToMove);
- #elif defined(FW_BUILD_WIN)
- ::FW_PrimitiveCopyMemory(source, destination, bytesToMove);
- #endif
- }
-
- //----------------------------------------------------------------------------------------
- // FW_CMemoryManager::SetMemory -
- //----------------------------------------------------------------------------------------
- void FW_CMemoryManager::SetMemory(void *aBlock,
- unsigned long bytesToSet,
- unsigned char byteValue)
- {
- FW_ASSERT(aBlock != 0);
-
- register char *cp;
- cp = (char *)aBlock;
- while (bytesToSet--)
- *cp++ = byteValue;
- }
-
- //----------------------------------------------------------------------------------------
- // InitializeRawBlock - Set a raw block of fMemory to known values.
- //----------------------------------------------------------------------------------------
- void FW_CMemoryManager::InitializeRawBlock(void *aBlock, unsigned long sizeBlock)
- {
- #ifdef FW_DEBUG
- SetMemory(aBlock, sizeBlock, kKnownRawByte);
- #endif
- }
-
- //----------------------------------------------------------------------------------------
- // FW_CMemoryManager::AllocateBlock - Allocate a non-relocatable block of fMemory.
- //----------------------------------------------------------------------------------------
- void* FW_CMemoryManager::AllocateBlock(unsigned long bytesRequested)
- {
- unsigned long bytesNeeded = bytesRequested;
- void* aBlock = FW_PrimitiveAllocateBlock(bytesNeeded);
- if (aBlock == 0)
- FW_Failure(FW_xMemoryExhausted);
-
- InitializeRawBlock(aBlock, bytesNeeded);
-
- return aBlock;
- }
-
- #ifdef FW_BUILD_MAC
- #pragma segment FWMemMgr2
- #endif
-
- //----------------------------------------------------------------------------------------
- // FW_CMemoryManager::ResizeBlock - Resize a non-relocatable block of fMemory. The
- // block may be moved to a new location if necessary.
- //----------------------------------------------------------------------------------------
- void *FW_CMemoryManager::ResizeBlock(void *aBlock, unsigned long bytesRequested)
- {
- unsigned long bytesNeeded = bytesRequested;
-
- void *newBlock;
- if (aBlock == 0)
- newBlock = FW_PrimitiveAllocateBlock(bytesNeeded);
- else
- newBlock = FW_PrimitiveResizeBlock(aBlock, bytesNeeded);
-
- if (newBlock == 0)
- FW_Failure(FW_xMemoryExhausted);
-
- return newBlock;
- }
-
- //----------------------------------------------------------------------------------------
- // FW_CMemoryManager::FreeBlock - Return a non-relocatable block to the free store.
- //----------------------------------------------------------------------------------------
- void FW_CMemoryManager::FreeBlock(void *aBlock)
- {
- if (aBlock != 0)
- FW_PrimitiveFreeBlock(aBlock);
- }
-
- //----------------------------------------------------------------------------------------
- // FW_CMemoryManager::AllocateSystemHandle -
- //----------------------------------------------------------------------------------------
- FW_PlatformHandle FW_CMemoryManager::AllocateSystemHandle(unsigned long bytesNeeded)
- {
- FW_PlatformHandle aSystemHandle;
-
- #if !defined FW_qUsePlatformAlloc
- aSystemHandle = (FW_PlatformHandle) ::MMAllocateHandle(bytesNeeded);
- #elif defined FW_BUILD_MAC
- aSystemHandle = ::NewHandle(bytesNeeded);
- #elif defined FW_BUILD_WIN
- aSystemHandle = ::GlobalAlloc(GMEM_MOVEABLE, bytesNeeded);
- #endif
-
- if (aSystemHandle == 0)
- FW_Failure(FW_xMemoryExhausted);
-
- return aSystemHandle;
- }
-
- #ifdef FW_BUILD_MAC
- #pragma segment FWMemMgr3
- #endif
-
- //----------------------------------------------------------------------------------------
- // FW_CMemoryManager::ResizeSystemHandle -
- //----------------------------------------------------------------------------------------
- FW_PlatformHandle FW_CMemoryManager::ResizeSystemHandle(FW_PlatformHandle aHandle,
- unsigned long bytesNeeded)
- {
- FW_ASSERT(aHandle != 0);
-
- FW_PlatformHandle newHandle = aHandle;
-
- #if !defined FW_qUsePlatformAlloc
- ::MMSetHandleSize(aHandle, bytesNeeded);
- #elif defined FW_BUILD_MAC
- ::SetHandleSize(aHandle, bytesNeeded);
- #elif defined FW_BUILD_WIN
- newHandle = ::GlobalReAlloc(aHandle, bytesNeeded, GMEM_MOVEABLE);
- #endif
-
- if (newHandle == 0 || GetSystemHandleSize(newHandle) < bytesNeeded)
- FW_Failure(FW_xMemoryExhausted);
-
- return newHandle;
- }
-
- #ifdef FW_BUILD_MAC
- #pragma segment FWMemMgr2
- #endif
-
- //----------------------------------------------------------------------------------------
- // FW_CMemoryManager::FreeSystemHandle -
- //----------------------------------------------------------------------------------------
- void FW_CMemoryManager::FreeSystemHandle(FW_PlatformHandle aHandle)
- {
- #if !defined FW_qUsePlatformAlloc
- if (aHandle)
- ::MMFreeHandle(aHandle);
- #elif defined FW_BUILD_MAC
- if (aHandle)
- ::DisposeHandle(aHandle);
- #elif defined FW_BUILD_WIN
- if (aHandle)
- ::GlobalFree(aHandle);
- #endif
- }
-
- #ifdef FW_BUILD_MAC
- #pragma segment FWMemMgr4
- #endif
-
- //----------------------------------------------------------------------------------------
- // FW_CMemoryManager::LockSystemHandle -
- //----------------------------------------------------------------------------------------
- void * FW_CMemoryManager::LockSystemHandle(FW_PlatformHandle handle)
- {
- FW_ASSERT(handle != 0);
-
- void* memory;
-
- #if !defined FW_qUsePlatformAlloc
- memory = ::MMLockHandle(handle);
- #elif defined FW_BUILD_MAC
- HLock(handle);
- memory = *handle;
- #elif defined FW_BUILD_WIN
- memory = ::GlobalLock(handle);
- #endif
-
- if(memory == NULL)
- FW_Failure(FW_xMemoryExhausted);
-
- return memory;
- }
-
- #ifdef FW_BUILD_MAC
- #pragma segment FWMemMgr5
- #endif
-
- //----------------------------------------------------------------------------------------
- // FW_CMemoryManager::UnlockSystemHandle -
- //----------------------------------------------------------------------------------------
- void FW_CMemoryManager::UnlockSystemHandle(FW_PlatformHandle aHandle)
- {
- FW_ASSERT(aHandle != 0);
-
- #if !defined FW_qUsePlatformAlloc
- ::MMUnlockHandle(aHandle);
- #elif defined FW_BUILD_MAC
- ::HUnlock(aHandle);
- #elif defined FW_BUILD_WIN
- ::GlobalUnlock(aHandle);
- #endif
- }
-
-
- #ifdef FW_BUILD_MAC
- #pragma segment FWMemMgr6
- #endif
-
- //----------------------------------------------------------------------------------------
- // FW_CMemoryManager::GetSystemHandleSize -
- //----------------------------------------------------------------------------------------
- unsigned long FW_CMemoryManager::GetSystemHandleSize(FW_PlatformHandle aHandle)
- {
- FW_ASSERT(aHandle != 0);
-
- #if !defined FW_qUsePlatformAlloc
- return ::MMGetHandleSize(aHandle);
- #elif defined FW_BUILD_MAC
- return ::GetHandleSize(aHandle);
- #elif defined FW_BUILD_WIN
- return ::GlobalSize(aHandle);
- #endif
- }
-
- //----------------------------------------------------------------------------------------
- // FW_CMemoryManager::CopySystemHandle -
- //----------------------------------------------------------------------------------------
- FW_PlatformHandle FW_CMemoryManager::CopySystemHandle(FW_PlatformHandle aHandle)
- {
- FW_PlatformHandle newHandle = NULL;
-
- #if !defined FW_qUsePlatformAlloc
- newHandle = (FW_PlatformHandle) ::MMCopyHandle(aHandle);
- #else
- unsigned long size = GetSystemHandleSize(aHandle);
-
- FW_CAcquireLockedSystemHandle sourceLock(aHandle);
- void *sourcePointer = sourceLock.GetPointer();
-
- newHandle = AllocateSystemHandle(size);
- FW_CAcquireLockedSystemHandle destinationLock(newHandle);
- void *destinationPointer = destinationLock.GetPointer();
-
- CopyMemory(sourcePointer, destinationPointer, size);
- #endif
-
- return newHandle;
- }
-
- #ifdef FW_BUILD_MAC
- #pragma segment FWMemMgr7
- #endif
-
- //========================================================================================
- // C++ Global operator new & delete
- //========================================================================================
-
- #ifdef FW_OPERATOR_NEW_SIZE_T_VOIDSTAR
- //----------------------------------------------------------------------------------------
- // operator new
- //----------------------------------------------------------------------------------------
-
- void *operator new(size_t /* size */,void *p)
- {
- return p;
- }
- #endif
-
- //----------------------------------------------------------------------------------------
- // operator new
- //----------------------------------------------------------------------------------------
- void* operator new(size_t size)
- {
-
- FW_SPrivMemoryGlobals& globals = FW_CMemoryTaskGlobals::GetMemoryGlobals();
- void* p;
-
- globals.gLastRequested = size;
-
- while ((p = FW_PrimitiveAllocateBlock(size)) == 0)
- {
- void (*newHandler)();
-
- #ifdef FW_SET_NEW_HANDLER
- newHandler = globals.gNewHandler;
- #else
- // Fetch (and restore) the current handler. ARM 280-281 uses _new_handler as a
- // global, but I don't know if that's the official definition.
- newHandler = ::set_new_handler(0);
- ::set_new_handler(newHandler);
- #endif
- if (newHandler)
- newHandler();
- else
- return 0;
- }
-
- return p;
- }
-
- //----------------------------------------------------------------------------------------
- // operator delete
- //----------------------------------------------------------------------------------------
- void operator delete(void *pObject)
- {
- FW_CMemoryManager::FreeBlock(pObject);
- }
-